﻿using UnityEngine;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace CWM.Skinn
{
    public static partial class SkinnEx
    {
        public static bool CloneSkinnedTo(this Renderer source, out SkinnedMeshRenderer smr,
            Transform a, Transform b = null, Transform c = null, Transform d = null)
        {
            smr = null;
            if (!a || IsNullOrNotVailid(source) ) return false;

            var root = source.transform.root;
            var position = root.position; var rotation = root.rotation; var localScale = root.localScale;
            root.ResetLocal();

            var mesh = source.BakeCustom(true, true, false, false);

            var smrGo = new GameObject(source.name);
            smr = smrGo.AddComponent<SkinnedMeshRenderer>();
            var boneWeights = new BoneWeight[mesh.vertices.Length];
            var vertices = mesh.vertices;
            var bones = new List<Transform>(4);

            if (!b && !c && !d) bones.Add(a);
            else { if (a) bones.Add(a); if (b) bones.Add(b); if (c) bones.Add(c); if (d) bones.Add(d); }

            for (int i = 0; i < boneWeights.Length; i++)
            {
                var boneWeight = new BoneWeightData();
                int boneCount = Mathf.Min(Mathf.Min(bones.Count, boneWeight.weights.Length));
                if (boneCount == 1) { boneWeights[i] = boneWeight; continue; }
                for (int ii = 0; ii < boneCount; ii++)
                {
                    boneWeight.weights[i].x = i;
                    boneWeight.weights[i].y = Vector3.Distance(bones[i].position, vertices[i]);
                }
                boneWeight.Clamp();
                boneWeights[i] = boneWeight;
            }

            smr.sharedMesh = mesh;
            smr.sharedMesh.name = EnforceObjectName(smr.sharedMesh);
            smr.rootBone = bones.FindMinHierarchicalOrder();
            smr.bones = bones.ToArray();
            smr.sharedMesh.boneWeights = boneWeights;
            smr.sharedMesh.bindposes = GetBindposes(smr.bones);
            smr.sharedMaterials = source.sharedMaterials;
            smr.transform.SetParent(source.transform.root);

            root.position = position; root.rotation = rotation; root.localScale = localScale;

            return true;
        }
    }
}
